<?php

namespace App\Services;

use App\Models\College;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;

class CollegeSpiderService
{
    private $client;
    private $logger;
    private $proxy_enable = false;
    private $timeout = 10;
    private $maxRetries = 3;

    public function __construct(bool $proxy_enable = false)
    {
        $this->client = new Client([
            'base_uri' => 'https://static-data.gaokao.cn/www/2.0/school/',
            'timeout' => $this->timeout,
            'headers' => [
                'Referer' => 'https://www.gaokao.cn/',
                'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
            ]
        ]);

        // 确保logs目录存在
        $logDir = dirname(__DIR__, 2).'/storage/logs';
        if (!is_dir($logDir)) {
            mkdir($logDir, 0755, true);
        }
        
        $this->logger = new Logger('college-spider');
        $this->logger->pushHandler(new StreamHandler($logDir.'/college-spider.log'));
    }

    /*
     * 采集院校专业信息+男女比例
     */
    public function crawlCollegeOtherBaseInfo(College $college): bool
    {
        return $this->withRetry(function() use ($college) {
            $url = "{$college->school_id}/pc_jobdetail.json?a=www.gaokao.cn";
            $response = $this->makeRequest($url);
            if ($response) {
                $data = json_decode($response, true);
                $this->saveOtherInfo($college, $data['data'] ?? []);
                return true;
            }

            return false;
        }, $college);
    }

    /**
     * 采集院校详情
     */
    public function crawlCollegeDetail(College $college): bool
    {
        return $this->withRetry(function() use ($college) {
            $url = "{$college->school_id}/info.json?a=www.gaokao.cn";
            $response = $this->makeRequest($url);

            if ($response) {
                $data = json_decode($response, true);
                $this->logger->info("采集数据: {$college->college_name}", $data);
                $this->saveDetailInfo($college, $data['data'] ?? []);
                return true;
            }

            return false;
        }, $college);
    }

    public function crawlCollegeContent(College $college): bool
    {
        return $this->withRetry(function() use ($college) {
            $url = "{$college->school_id}/detail/69000.json?a=www.gaokao.cn";
            $response = $this->makeRequest($url);

            if ($response) {
                $data = json_decode($response, true);
                $this->logger->info("采集数据: {$college->college_name}", $data);
                $this->saveContent($college, $data['data'] ?? []);
                return true;
            }

            return false;
        }, $college);
    }

    /**
     * 带重试机制的请求封装
     */
    private function withRetry(callable $callback, College $college): bool
    {
        $attempts = 0;
        $lastError = null;

        while ($attempts < $this->maxRetries) {
            try {
                if ($callback()) {
                    return true;
                }
            } catch (\Exception $e) {
                $lastError = $e->getMessage();
                $this->logger->error("采集失败: {$lastError}", ['school_id' => $college->school_id]);
            }

            $attempts++;
            sleep(1); // 简单的延迟防止过快重试
        }

        if ($lastError) {
            $college->recordError($lastError);
        }

        return false;
    }

    /**
     * 发起HTTP请求
     */
    private function makeRequest(string $url): ?string
    {
        try {
            $options = [];
            $proxy_address = "http://127.0.0.1:1080";
            // if ($this->proxy_enable) {
            $options['proxy'] = $proxy_address;
            // }
            $response = $this->client->get($url, $options);
            return $response->getBody()->getContents();
        } catch (RequestException $e) {
            $this->logger->error("请求失败: {$e->getMessage()}", ['url' => $url]);
            throw $e;
        }
    }

    /**
     * 保存详情信息
     */
    private function saveDetailInfo(College $college, array $data): void
    {
        $updateData = [
            'introduction' => $data['content'] ?? null,
            // 'province_name' => $data['province_name'] ?? null,
            // 'city' => $data['city_name'] ?? null,
            // 'address' => $data['address'] ?? null,
            // 'official_url' => $data['school_site'] ?? null,
            // 'enroll_website' => $data['site'] ?? null,
            // 'department' => $data['belong'] ?? null,
            // 'nature' => $data['nature_name'] ?? null,
            // 'education_level' => $data['level_name'] ?? null,
            // 'create_year' => $data['create_date'] ?? null,
            // 'rank' => $data['ruanke_rank'] ?? null,
//            'college_phone' => $data['phone'] ?? null,
//            'recruit_phone' => $data['recruit_tel'] ?? null,
//             'category' => $data['type_name'] ?? null,
//            'characteristic' => $data['characteristic'] ?? null,
//            'research_teaching' => sprintf("%s %s %s", $data['num_doctor']?:"博士点 " . $data['num_doctor'], $data['num_master']??"硕士点 " . $data['num_doctor'], $data['num_subject']??"重点学科 " . $data['num_subject']),
            'postgraduate_proportion' => $data['recommend_master_rate'] ?? null,
//            'boys_proportion' => $data['boys_proportion'] ?? null, //男女比例
//            'scholarship' => $data['scholarship'] ?? null,  //院校奖学金


//            'college_scenery' => $data['school_scenery'] ?? null, //院校风光
//            "logo_url" => $data['logo'] ?? null, //院校logo图片地址


//            'public_address' => $data['public_address'] ?? null, //公众号图片地址
//            'canteen_dormitory' => $data['canteen_dormitory'] ?? null, //食堂宿舍
//            'college_affiliation' => $data['college_affiliation'] ?? null,
//            'employment_proportion' => $data['employment_proportion'] ?? null, //就业率
            'is_yikao' => $data['is_yikao'] ?? 0,
            // 'yk_type' => $data['yk_type'][0] ?? null, //艺考类型
        ];

        $research_teaching = '';
        if($data['num_doctor']) {
            $research_teaching .=  '博士点 ' . $data['num_doctor'] . ' ';
        }
        if($data['num_master']) {
            $research_teaching .=  '硕士点 ' . $data['num_master'] . ' ' ;
        }
        if($data['num_subject']) {
            $research_teaching .=  '重点学科 ' . $data['num_subject'];
        }

        $updateData['research_teaching'] = $research_teaching;

        $college->update($updateData);
        $college->markAsCrawled();
    }

    public function saveOtherInfo(College $college, array $data)
    {
        $updateData = [
            'boys_proportion' => $data['gradute'][0]['men_rate'] ?? null, //院校风光
        ];

        $college->update($updateData);
    }

    public function saveContent(College $college, array $data)
    {
        $updateData = [
            'content' => $data['content'] ?? '', //院校风光
        ];

        $college->update($updateData);
    }

    /**
     * 获取待采集的院校列表
     * @param int|null $limit 限制返回数量
     * @return \Illuminate\Support\Collection|College[]
     */
    public function getColleges(?int $limit = null)
    {
        $query = College::where('status', 0)
            ->orderBy('id');
            
        if ($limit) {
            $query->limit($limit);
        }

        return $query->get();
    }

    /**
     * 处理一批院校数据
     * @param array $colleges 院校集合
     */
    public function processBatch(array $colleges): void
    {
        foreach ($colleges as $college) {
            $this->crawlCollegeDetail($college);
            $this->crawlCollegeOtherBaseInfo($college);
            $this->crawlCollegeContent($college);
        }
    }

    /**
     * 处理单个院校数据
     * @param College $college 院校对象
     */
    public function processCollege(College $college): bool
    {
        $detailSuccess = $this->crawlCollegeDetail($college);
        $otherSuccess = $this->crawlCollegeOtherBaseInfo($college);
        $content = $this->crawlCollegeContent($college);
        return $detailSuccess && $otherSuccess && $content;
    }
}
